package com.uyayo.cms.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.uyayo.cms.entity.CmsArticleCategory;
import com.uyayo.cms.mapper.CmsArticleCategoryMapper;
import com.uyayo.cms.model.CmsArticleCategoryCondition;
import com.uyayo.cms.service.CmsArticleCategoryService;
import com.uyayo.framework.common.exception.CodeMultipleException;
import com.uyayo.framework.common.exception.ParentNotFoundException;
import com.uyayo.framework.pagehelper.pojo.OrderBy;
import com.uyayo.framework.pagehelper.pojo.PageBean;
import com.uyayo.framework.pagehelper.util.OrderByUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@Service("cmsArticleCategoryService")
public class CmsAricleCategoryServiceImpl implements CmsArticleCategoryService {


	private final CmsArticleCategoryMapper cmsArticleCategoryMapper;

	@Autowired
	public CmsAricleCategoryServiceImpl(CmsArticleCategoryMapper cmsArticleCategoryMapper) {
		this.cmsArticleCategoryMapper = cmsArticleCategoryMapper;
	}


	@Override
	public CmsArticleCategory getArticleCategoryById(Long id){
		return cmsArticleCategoryMapper.selectByPrimaryKey(id);
	}
	

	@Override
	public List<CmsArticleCategory> selectArticleCategory(CmsArticleCategoryCondition cmsArticleCategoryCondition) {
		Example example = new Example(CmsArticleCategory.class);
		Criteria criteria = example.createCriteria();
		if(Objects.nonNull(cmsArticleCategoryCondition.getStatus())){
			criteria.andEqualTo("status",cmsArticleCategoryCondition.getStatus());
		}
		if(Objects.nonNull(cmsArticleCategoryCondition.getHasChildren())){
			criteria.andEqualTo("hasChildren",cmsArticleCategoryCondition.getHasChildren());
		}
		if(Objects.nonNull(cmsArticleCategoryCondition.getParentId())){
			criteria.andEqualTo("parentId",cmsArticleCategoryCondition.getParentId());
		}
		if(Objects.nonNull(cmsArticleCategoryCondition.getMemberId())){
			criteria.andEqualTo("memberId",cmsArticleCategoryCondition.getMemberId());
		}
		return cmsArticleCategoryMapper.selectByExample(example);
	}
	
	@Override
	public PageBean<CmsArticleCategory> selectArticleCategoryByPaging(Integer pageCurrent, Integer pageSize, String sort, String order, CmsArticleCategoryCondition cmsArticleCategoryCondition) {

		List<CmsArticleCategory> userList;
		//分页处理
		List<OrderBy> orderBies = new ArrayList<>();
		orderBies.add(new OrderBy("createTime", "create_time"));
		orderBies.add(new OrderBy("updateTime", "update_time"));

		OrderByUtil  orderByUtil = new OrderByUtil();
		String orderBy = orderByUtil.getOrderBy(orderBies, sort, order);
		PageHelper.startPage(pageCurrent, pageSize);
		
		Example example = new Example(CmsArticleCategory.class);
		if(!StringUtils.isEmpty(orderBy)){
			example.setOrderByClause(orderBy);
		}
		Criteria criteria = example.createCriteria();
		if(!StringUtils.isEmpty(cmsArticleCategoryCondition.getName())){
			criteria.andLike("name","%"+cmsArticleCategoryCondition.getName()+"%");
		}
		if(cmsArticleCategoryCondition.getBeginCreateTime()!=null || cmsArticleCategoryCondition.getEndCreateTime()!=null){
			criteria.andBetween("createTime", cmsArticleCategoryCondition.getBeginCreateTime(), cmsArticleCategoryCondition.getEndCreateTime());
		}
		userList = cmsArticleCategoryMapper.selectByExample(example);

		//取记录总条数
		PageInfo<CmsArticleCategory> pageInfo = new PageInfo<>(userList);
		
		return new PageBean<>(pageInfo.getTotal(), pageCurrent, pageSize, userList);
	}
	

	@Override
	public int createCmsArticleCategory(CmsArticleCategory cmsArticleCategory) throws Exception {

		Long parentId = cmsArticleCategory.getParentId();

		if(!StringUtils.isEmpty(parentId)){
			CmsArticleCategory cmsArticleCategoryParent = getArticleCategoryById(parentId);
			if(cmsArticleCategoryParent==null){
				throw new ParentNotFoundException("Parent not found!");
			}
		}

		int count = cmsArticleCategoryMapper.insertSelective(cmsArticleCategory);
		if(count >0){
			updateHasChildrenToParent( parentId);
		}
		return count;

	}

	private int selectCountByParentId(Long parentId) {
		CmsArticleCategory cmsArticleCategory = new CmsArticleCategory();
		cmsArticleCategory.setParentId(parentId);
		return cmsArticleCategoryMapper.selectCount(cmsArticleCategory);
	}



	/**
	 * 修改父级是否含子级
	 * @param parentId 父资源id
	 */
	private void  updateHasChildrenToParent(Long parentId){
		if(!StringUtils.isEmpty(parentId)){
			CmsArticleCategory cmsArticleCategory = new CmsArticleCategory();
			cmsArticleCategory.setId(parentId);
			if(selectCountByParentId(parentId)>0) {
				cmsArticleCategory.setHasChildren(true);
			}else{
				cmsArticleCategory.setHasChildren(false);
			}
			cmsArticleCategoryMapper.updateByPrimaryKeySelective(cmsArticleCategory);
		}
	}

	@Override
	public CmsArticleCategory selectOne(CmsArticleCategory cmsArticleCategory) {
		return cmsArticleCategoryMapper.selectOne(cmsArticleCategory);
	}

	@Override
	public int updateArticleCategory(CmsArticleCategory cmsArticleCategory) throws Exception {

		CmsArticleCategory cmsArticleCategoryOld = getArticleCategoryById(cmsArticleCategory.getId());

		Long parentId = cmsArticleCategory.getParentId()==null?0:cmsArticleCategory.getParentId();
		if(parentId!=0){

			//获取修改的父级资源
			CmsArticleCategory cmsArticleCategoryParent = getArticleCategoryById(parentId);
			if(cmsArticleCategoryParent==null){
				throw new ParentNotFoundException("Parent not found!");
			}
			if (selectCountByParentId(cmsArticleCategoryOld.getId()) > 0) {
				Example example = new Example(CmsArticleCategory.class);
				Criteria criteria = example.createCriteria();
				criteria.andEqualTo("parentId",cmsArticleCategoryOld.getId());
				List<CmsArticleCategory> cmsArticleCategoryList = cmsArticleCategoryMapper.selectByExample(example);
				if (!cmsArticleCategoryList.isEmpty()) {
					for(CmsArticleCategory cmsArticleCategory_:cmsArticleCategoryList){
						if(Objects.equals(cmsArticleCategory_.getId(), parentId)){
							cmsArticleCategoryParent.setParentId(cmsArticleCategoryOld.getParentId());
							cmsArticleCategoryMapper.updateByPrimaryKeySelective(cmsArticleCategoryParent);
						}else{
							recursiveCheckParentIsChildren(cmsArticleCategoryOld.getParentId(),cmsArticleCategory.getParentId(),cmsArticleCategory,cmsArticleCategoryParent);
						}
					}
				}
			}
		}
		if(selectCountByParentId(cmsArticleCategory.getId())>0) {
			cmsArticleCategory.setHasChildren(true);
		}else{
			cmsArticleCategory.setHasChildren(false);
		}
		int count = cmsArticleCategoryMapper.updateByPrimaryKeySelective(cmsArticleCategory);
		if(count<=0){
			return count;
		}
		updateHasChildrenToParent(parentId);
		if(cmsArticleCategoryOld!=null){
			updateHasChildrenToParent(cmsArticleCategoryOld.getParentId());
		}
		return count;
	}


	/**
	 * 迭代检查选择的上级id是否是自己的子级
	 * @param parentIdOld 原上级id
	 * @param parentIdNew	新上级id
	 * @param cmsArticleCategoryChild 子机构
	 * @param cmsArticleCategoryParent 父机构
	 */
	private void recursiveCheckParentIsChildren(Long parentIdOld, Long parentIdNew, CmsArticleCategory cmsArticleCategoryChild, CmsArticleCategory cmsArticleCategoryParent){
		if (selectCountByParentId(cmsArticleCategoryChild.getId()) > 0) {
			Example example = new Example(CmsArticleCategory.class);
			Criteria criteria = example.createCriteria();
			criteria.andEqualTo("parentId",cmsArticleCategoryChild.getId());
			List<CmsArticleCategory> cmsArticleCategoryList = cmsArticleCategoryMapper.selectByExample(example);
			if (!cmsArticleCategoryList.isEmpty()) {
				for(CmsArticleCategory cmsArticleCategory:cmsArticleCategoryList){
					if(Objects.equals(cmsArticleCategory.getId(), parentIdNew)){
						cmsArticleCategoryParent.setParentId(parentIdOld);
						cmsArticleCategoryMapper.updateByPrimaryKeySelective(cmsArticleCategoryParent);
					}else {
						recursiveCheckParentIsChildren(parentIdOld, parentIdNew, cmsArticleCategory, cmsArticleCategoryParent);
					}
				}
			}
		}
	}

	@Override
	public int deleteArticleCategory(Long id) {
		return cmsArticleCategoryMapper.deleteByPrimaryKey(id);
	}

	@Override
	public List<CmsArticleCategory> selectCmsCategoryListByArticleId(Long articleId){
		return cmsArticleCategoryMapper.selectCmsArticleCategoryList(articleId);
	}

}
